package com.mxl.mvc.cashorder;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.MessageFormat;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

import com.mxl.common.MD5Util;
import com.mxl.common.StringUtil;
import com.mxl.common.WebUtils;
import com.mxl.common.helper.DirectFlag;
import com.mxl.common.helper.RemoteType;
import com.mxl.common.helper.ResponseErrorCode;
import com.mxl.service.cashorder.GatewayDispatchService;
import com.mxl.service.cashorder.dto.CashOrderRequest;

/**
 * 网关支付转向控制器.
 * 
 * @version 1.0
 */
public final class GatewayDispatchController extends AbstractController {
	private static final Logger logger = LoggerFactory
			.getLogger(GatewayDispatchController.class);
	private GatewayDispatchService gatewayDispatchService;

	private static final String DEFUL_URL = "jsp/gateway";
	private String errorView;

	@SuppressWarnings("unchecked")
	protected ModelAndView handleRequestInternal(
			final HttpServletRequest request, final HttpServletResponse response)
			throws Exception {
		request.setCharacterEncoding("UTF-8");
		// 验证商户提交的重要参数 直接返回错误码 /验证金额
		String orderId = request.getParameter("order_id");
		String merchantAcctId = request.getParameter("member_code");
		String msgId = GatewayRequestValidate.checkRequest(request);
		if (!StringUtil.isEmpty(msgId)) {
			logger.info("GatewayDispatchController request map :"
					+ request.getParameterMap());
			responseReturnContent(
					response,
					new StringBuilder().append(merchantAcctId).append("|")
							.append(orderId).append("|").append(msgId)
							.append("|").append("接口参数不能为空,请检查.").toString());
			return null;
		}
		// 组装请求
		CashOrderRequest req = wrapRequest(request);

		// 保存商户请求 验证商户参数
		gatewayDispatchService.dispatch(req);

		// 商户是直连还是非直连 （直连和非直连验证的信息不一样） 某一步出错 就保存错误的日志 后面公用收单流程 然后进入是否走慢充。最后选择渠道
		// 保存匹配订单和渠道订单 送渠道

		// 直连则进入收单流程 不是直连 则组装商户定制的信息 调整到商户定制的页面
		// 根据错误码去获取 错误码信息
		WebApplicationContext rc = WebApplicationContextUtils
				.getWebApplicationContext(request.getSession()
						.getServletContext());
		req.setMsgDesc(rc.getMessage(req.getMsgId(), null, Locale.CHINESE));
		if (DirectFlag.DIRECT.getValue() == req.getDirectFlag()) {
			if (req.getRetmode() == null) {
				responseReturnContent(response, getXmlResponse(request, req));
			} else if (RemoteType.VIEW.getValue().equalsIgnoreCase(
					req.getRetmode())) {
				return new ModelAndView(errorView).addObject("request", req);
			} else if (RemoteType.TXT.getValue().equalsIgnoreCase(
					req.getRetmode())) {
				StringBuilder returnContent = getResponse(request, req);
				responseReturnContent(response, returnContent.toString());
			} else {
				responseReturnContent(response, getXmlResponse(request, req));
			}
			return null;
		}
		// 标准网关页面 组装数据 和参数 页面的金额等 跳转到指定的页面
		String url = errorView;
		if (StringUtil.isEmpty(req.getMsgId())
				|| ResponseErrorCode.SUCC.getValue().equalsIgnoreCase(
						req.getMsgId())) {
			url = DEFUL_URL;
			req.setMsgDesc("");
			if (req.getCustomMerchant() != null) {
				url = req.getCustomMerchant().get(0).getRedirectUrl() == null ? url
						: req.getCustomMerchant().get(0).getRedirectUrl();
			}
		}
		return new ModelAndView(url).addObject("request", req);
	}

	private StringBuilder getResponse(final HttpServletRequest request,
			CashOrderRequest req) {
		StringBuilder returnContent = new StringBuilder();
		returnContent.append(req.getVersion()).append("|")
				.append(req.getMemberCode()).append("|").append(getSign(req))
				.append("|").append(req.getOrderTime()).append("|")
				.append(req.getOrderId()).append("|")
				.append(req.getOrderAmount()).append("|")
				.append(req.getMsgId()).append("|").append(req.getMsgDesc());
		return returnContent;
	}

	private String getXmlResponse(final HttpServletRequest request,
			CashOrderRequest req) {
		String result = MessageFormat
				.format("<?xml version=\"1.0\" encoding=\"utf-8\" ?><response><version>{0}</version><member_code>{1}</member_code><sign_msg>{2}</sign_msg><order_time>{3}</order_time><order_id>{4}</order_id><order_amount>{5}</order_amount><ret_code>{6}</ret_code><ret_msg>{7}</ret_msg></response>",
						req.getVersion(), req.getMemberCode(), getSign(req),
						req.getOrderTime(), req.getOrderId(), req
								.getOrderAmount().toString(), req.getMsgId(),
						req.getMsgDesc());
		logger.info("gateway response xml:" + result);
		return result;
	}

	private String getSign(CashOrderRequest c) {
		String key = (c.getCustomMerchant() != null && c.getCustomMerchant()
				.size() > 0) ? c.getCustomMerchant().get(0).getMacKey() : "";
		String signO = MessageFormat
				.format("version={0}member_code={1}order_time={2}order_id={3}order_amount={4}ret_code={5}merchant_key={6}",
						c.getVersion(), c.getMemberCode(), c.getOrderTime(),
						c.getOrderId(), String.valueOf(c.getOrderAmount()),
						c.getMsgId(), key);
		logger.info("gateway membercode response returnContent---:" + signO);
		return MD5Util.md5Hex(signO);
	}

	/**
	 * 包装网关传递过来的参数.
	 * 
	 * @param request
	 *            从商户传递过来的请求对象
	 * @return gatewayRequestDTO 包装的网关请求对象
	 */
	@SuppressWarnings({ "unchecked", "unused" })
	private CashOrderRequest wrapRequest(final HttpServletRequest request) {
		CashOrderRequest gatewayRequestDTO = new CashOrderRequest();
		String orderId = request.getParameter("order_id");
		String memberCode = request.getParameter("member_code");
		String orderAmount = request.getParameter("order_amount");
		String url = request.getParameter("notify_url");
		String redirect_url = request.getParameter("redirect_url");
		gatewayRequestDTO.setRedirectUrl(redirect_url);
		gatewayRequestDTO.setOrderId(orderId.trim());
		gatewayRequestDTO.setMemberCode(memberCode.trim());
		gatewayRequestDTO.setOrderAmount(Long.valueOf(orderAmount.trim()));
		gatewayRequestDTO.setChannel("web");
		gatewayRequestDTO.setExt1(request.getParameter("ext1"));
		gatewayRequestDTO.setExt2(request.getParameter("ext2"));
		gatewayRequestDTO.setNotifyUrl(url.trim());
		gatewayRequestDTO.setRetmode(request.getParameter("ret_mode"));
		gatewayRequestDTO.setVersion(request.getParameter("version"));
		gatewayRequestDTO.setSignMsg(request.getParameter("sign_msg"));
		gatewayRequestDTO.setProductName(request.getParameter("product_name"));
		gatewayRequestDTO.setOrderTime(request.getParameter("order_time"));
		gatewayRequestDTO.setCardNo(request.getParameter("card_no"));
		gatewayRequestDTO.setCardPwd(request.getParameter("card_pwd"));
		gatewayRequestDTO.setIp(WebUtils.getIp(request));
		return gatewayRequestDTO;
	}

	/**
	 * 直接返回内容.
	 * 
	 * @param response
	 * @param content
	 */
	private void responseReturnContent(HttpServletResponse response,
			String content) {
		response.setCharacterEncoding("UTF-8");
		PrintWriter writer = null;
		try {
			writer = response.getWriter();
			writer.write(content);
			writer.flush();
		} catch (IOException e) {
			logger.error("responseReturnContent error", e);
		} finally {
			if (writer != null) {
				writer.close();
			}
		}

	}

	public void setGatewayDispatchService(
			GatewayDispatchService gatewayDispatchService) {
		this.gatewayDispatchService = gatewayDispatchService;
	}

	public void setErrorView(String errorView) {
		this.errorView = errorView;
	}

}
